package com.ja.openchat;

import android.annotation.SuppressLint;
import android.app.Application;

import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;

import com.ja.openchat.data.LoginRepository;
import com.ja.openchat.viewmodels.AddContactFragmentViewModel;
import com.ja.openchat.viewmodels.AddContactViewModel;
import com.ja.openchat.viewmodels.C2CActivityViewModel;
import com.ja.openchat.viewmodels.ChatViewmodel;
import com.ja.openchat.viewmodels.ContactChooseViewModel;
import com.ja.openchat.viewmodels.ContactDetailSingleViewModel;
import com.ja.openchat.viewmodels.ContactDetailViewModel;
import com.ja.openchat.viewmodels.EditGroupManagerViewModel;
import com.ja.openchat.viewmodels.EditGroupViewModel;
import com.ja.openchat.viewmodels.EditUserProfileViewModel;
import com.ja.openchat.viewmodels.FileDisplayViewModel;
import com.ja.openchat.viewmodels.ForwardViewModel;
import com.ja.openchat.viewmodels.GroupChatManagerViewModel;
import com.ja.openchat.viewmodels.GroupChatSettingNewViewModel;
import com.ja.openchat.viewmodels.GroupChatSettingSingleViewModel;
import com.ja.openchat.viewmodels.GroupInviteLinkViewModel;
import com.ja.openchat.viewmodels.GroupRestrictedViewModel;
import com.ja.openchat.viewmodels.LocationActivityViewModel;
import com.ja.openchat.viewmodels.LoginViewModel;
import com.ja.openchat.viewmodels.MainViewModel;
import com.ja.openchat.viewmodels.MobileContactActivityViewModel;
import com.ja.openchat.viewmodels.ModifyFiledViewModel;
import com.ja.openchat.viewmodels.MsgViewModel;
import com.ja.openchat.viewmodels.PostRedViewModel;
import com.ja.openchat.viewmodels.PublicChatSearchViewModel;
import com.ja.openchat.viewmodels.RedPacketDetailViewModel;
import com.ja.openchat.viewmodels.ScanViewModel;
import com.ja.openchat.viewmodels.SplashViewModel;

public class AppViewModelFactory extends ViewModelProvider.NewInstanceFactory {
    @SuppressLint("StaticFieldLeak")
    private static volatile AppViewModelFactory INSTANCE;
    private final Application mApplication;
    private final LoginRepository mRepository;

    public static AppViewModelFactory getInstance(Application application) {
        if (INSTANCE == null) {
            synchronized (AppViewModelFactory.class) {
                if (INSTANCE == null) {
                    INSTANCE = new AppViewModelFactory(application, Injection.provideLoginRepository());
                }
            }
        }
        return INSTANCE;
    }

    @VisibleForTesting
    public static void destroyInstance() {
        INSTANCE = null;
    }

    private AppViewModelFactory(Application application, LoginRepository repository) {
        this.mApplication = application;
        this.mRepository = repository;
    }

    @NonNull
    @Override
    public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
        if (modelClass.isAssignableFrom(LoginViewModel.class)) {
            return (T) new LoginViewModel(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(MsgViewModel.class)) {
            return (T) new MsgViewModel(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(SplashViewModel.class)) {
            return (T) new SplashViewModel(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(AddContactViewModel.class)) {
            return (T) new AddContactViewModel(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(AddContactFragmentViewModel.class)) {
            return (T) new AddContactFragmentViewModel(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(ScanViewModel.class)) {
            return (T) new ScanViewModel(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(MainViewModel.class)) {
            return (T) new MainViewModel(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(ChatViewmodel.class)) {
            return (T) new ChatViewmodel(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(MobileContactActivityViewModel.class)) {
            return (T) new MobileContactActivityViewModel(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(C2CActivityViewModel.class)) {
            return (T) new C2CActivityViewModel(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(LocationActivityViewModel.class)) {
            return (T) new LocationActivityViewModel(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(PostRedViewModel.class)) {
            return (T) new PostRedViewModel(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(ContactDetailViewModel.class)) {
            return (T) new ContactDetailViewModel(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(GroupChatSettingNewViewModel.class)) {
            return (T) new GroupChatSettingNewViewModel(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(GroupRestrictedViewModel.class)) {
            return (T) new GroupRestrictedViewModel(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(ModifyFiledViewModel.class)) {
            return (T) new ModifyFiledViewModel(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(ContactChooseViewModel.class)) {
            return (T) new ContactChooseViewModel(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(EditGroupViewModel.class)) {
            return (T) new EditGroupViewModel(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(EditUserProfileViewModel.class)) {
            return (T) new EditUserProfileViewModel(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(RedPacketDetailViewModel.class)) {
            return (T) new RedPacketDetailViewModel(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(PublicChatSearchViewModel.class)) {
            return (T) new PublicChatSearchViewModel(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(ForwardViewModel.class)) {
            return (T) new ForwardViewModel(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(GroupChatManagerViewModel.class)) {
            return (T) new GroupChatManagerViewModel(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(FileDisplayViewModel.class)) {
            return (T) new FileDisplayViewModel(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(GroupInviteLinkViewModel.class)) {
            return (T) new GroupInviteLinkViewModel(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(ContactDetailSingleViewModel.class)) {
            return (T) new ContactDetailSingleViewModel(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(GroupChatSettingSingleViewModel.class)) {
            return (T) new GroupChatSettingSingleViewModel(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(EditGroupManagerViewModel.class)) {
            return (T) new EditGroupManagerViewModel(mApplication, mRepository);
        }
        throw new IllegalArgumentException("Unknown ViewModel class: " + modelClass.getName());
    }
}
